/*
 * PBoostSocketSerivce.cpp
 *
 *  Created on: May 19, 2014
 *      Author: yuliang
 */

#include "PBoostSocketSerivce.h"

#include "PLog.h"

void CTcpAccentClient::OnReceive(const char *d, uint32_t l, void *c) {
	m_ser->receive_haddle(d, l, c);
}

void CTcpAccentClient::OnDisconnect(void *c) {
	m_ser->disconnect_haddle(c);
}

void CTcpAccentClient::OnWriteError(const char *d, uint32_t l, void *c) {
	m_ser->writeerr_haddle(d, l, c);
}

CTcpService::CTcpService(io_service& ioservice, uint16_t port, uint32_t maxBufSize) :
		CClientCallbackBase(maxBufSize), m_IoServ(ioservice), m_AcceptServ(NULL) {
	// TODO Auto-generated constructor stub
	addservice(port);
}

CTcpService::~CTcpService() {
	// TODO Auto-generated destructor stub
	if (NULL != m_AcceptServ) {
		m_AcceptServ->close();
		delete m_AcceptServ;
	}

	while (m_SetClients.begin() != m_SetClients.end()) {
		RemoveClient(*m_SetClients.begin());
	}
}

void CTcpService::addservice(uint16_t port) {
	tcp::endpoint tEndPoint = tcp::endpoint(tcp::v4(), port);
	m_AcceptServ = new tcp::acceptor(m_IoServ, tEndPoint);
	MLOG_TRACE(LOG4CPLUS_TCP_SOCKET, "bind|ip|" << tEndPoint.address().to_string() << "|port|" << port);

	CTcpAccentClient *cli = new CTcpAccentClient(m_IoServ, m_MaxBufSize, this);
	m_AcceptServ->async_accept(cli->GetSocket(),
			boost::bind(&CTcpService::acp_haddle, this, placeholders::error, m_AcceptServ, cli));
}

void CTcpService::acp_haddle(const error_code &err, tcp::acceptor* acc, CTcpAccentClient *cli) {
	if (err) {
		MLOG_ERROR(LOG4CPLUS_TCP_SOCKET, "accept error|" << "|" << err.message());
		return;
	}
	if (NULL == acc || NULL == cli) {
		MLOG_ERROR(LOG4CPLUS_TCP_SOCKET, "param error.");
		return;
	}

	m_SetClients.insert(cli);
	MLOG_TRACE(LOG4CPLUS_TCP_SOCKET, "accpet|" << acc->local_endpoint().port() << "|cliect size|" << m_SetClients.size());

	cli->start();
	OnAccept(cli);

	CTcpAccentClient *nextcli = new CTcpAccentClient(m_IoServ, m_MaxBufSize, this);
	acc->async_accept(nextcli->GetSocket(),
			boost::bind(&CTcpService::acp_haddle, this, placeholders::error, acc, nextcli));
}

